#include "stdafx.h"
#include "HistoryServiceClient.h"
#include "FCBinary.h"
#include "FCClientService.h"
#include "Security.h"
#include "DataCenter.h"
#include "StockService.h"


HistoryServiceClient::HistoryServiceClient(){
    setServiceID(10001);
    m_socketID = -1;
}

int HistoryServiceClient::getSocketID(){
    return m_socketID;
}

void HistoryServiceClient::setSocketID(int value){
    m_socketID = value;
}

void HistoryServiceClient::reqCodes(int requestID){
    FCBinary bw;
    bw.writeString(L"1");
    char* bytes = (char*)bw.getBytes();
    FCMessage fcm(getServiceID(), FUNCTIONID_GETCODE, requestID, m_socketID, 0, getCompressType(), bw.getBytesLen(), bytes);
    send(&fcm);
}

void HistoryServiceClient::reqData(int requestID, String code, int cycle, int subscription, double startDate, double endDate){
    FCBinary bw;
    bw.writeString(code);
    bw.writeInt(cycle);
    bw.writeDouble(startDate);
    bw.writeDouble(endDate);
    bw.writeInt(subscription);
    char* bytes = (char*)bw.getBytes();
    FCMessage fcm(getServiceID(), FUNCTIONID_GETDATA, requestID, m_socketID, 0, getCompressType(), bw.getBytesLen(), bytes);
    send(&fcm);
}

void HistoryServiceClient::reqData2(int requestID, String code, int oldRequestID){
    FCBinary bw;
    bw.writeString(code);
    bw.writeInt(oldRequestID);
    char* bytes = (char*)bw.getBytes();
    FCMessage fcm(getServiceID(), FUNCTIONID_GETDATA2, requestID, m_socketID, 0, getCompressType(), bw.getBytesLen(), bytes);
    send(&fcm);

}

void HistoryServiceClient::reqDevideDatas(int requestID){
    FCBinary bw;
    bw.writeInt(0);
    char* bytes = (char*)bw.getBytes();
    FCMessage fcm(getServiceID(), FUNCTIONID_GETDR, requestID, m_socketID, 0, getCompressType(), bw.getBytesLen(), bytes);
    send(&fcm);
}

ArrayList<SecurityData> HistoryServiceClient::getDatas(String *code, int *cycle, double *startDate, double *endDate, int *subscription, double *nowDate, double *nowVolume, double *nowAmount, char* body, int bodyLength){
    FCBinary br;
    br.write(body, bodyLength);
    *code = br.readString();
    *cycle = br.readInt();
    *startDate = br.readDouble();
    *endDate = br.readDouble();
    *subscription = br.readInt();
    *nowDate = br.readDouble();
    *nowVolume = br.readDouble();
    *nowAmount = br.readDouble();
    int datasSize = br.readInt();
    ArrayList<SecurityData> datas;
    bool seDate = (*cycle != 0 && *cycle != 1 && *cycle != 1440);
    for(int i = 0; i < datasSize; i++){
        SecurityData data;
        if(*cycle >= 1440)
        {
            data.m_date = br.readShort() * 86400;
        }
        else
        {
            data.m_date = br.readInt() * 60;
        }
        data.m_close = br.readDouble();
        data.m_high = br.readDouble();
        data.m_low = br.readDouble();
        data.m_open = br.readDouble();
        int type = br.readChar();
        if(type == 0)
        {
            data.m_volume = br.readDouble();
            data.m_amount = br.readDouble();
        }
        else
        {
            data.m_volume = br.readInt();
            data.m_amount = br.readInt();
        }
        if(seDate)
        {
            if(*cycle >= 1440)
            {
                data.m_startDate = br.readShort() *86400;
                data.m_endDate = br.readShort() * 86400;
            }
            else
            {
                data.m_startDate = br.readInt() * 60;
                data.m_endDate = br.readInt() * 60;
            }
        }
        if(*cycle > 0 && data.m_volume == 0)
        {
            continue;
        }
        datas.add(data);
        
    }
    return datas;
    
}

void HistoryServiceClient::getDatas2(String *code, ArrayList<SecurityData> *dayDatas, ArrayList<SecurityData> *minuteDatas, ArrayList<SecurityData> *trendDatas, char* body, int bodyLength){
    FCBinary br;
    br.write(body, bodyLength);
    *code = br.readString();
    ArrayList<SecurityData> *datas = 0;
    for (int d = 0; d < 3; d++)
    {
        if (d == 0)
        {
            datas = dayDatas;
        }
        else if (d == 1)
        {
            datas = minuteDatas;
        }
        else
        {
            datas = trendDatas;
        }
        int datasSize = br.readInt();
        for (int i = 0; i < datasSize; i++)
        {
            SecurityData data;
            if (d == 0)
            {
                data.m_date = br.readShort() * 86400;
            }
            else
            {
                data.m_date = br.readInt() * 60;
            }
            int type2 = br.readChar();
            if (type2 == 1)
            {
                data.m_close = (double)br.readShort() / 100;
                data.m_high = (double)br.readShort() /100;
                data.m_low = (double)br.readShort() /100;
                data.m_open = (double)br.readShort() / 100;
            }
            else
            {
                data.m_close = br.readDouble();
                data.m_high = br.readDouble();
                data.m_low = br.readDouble();
                data.m_open = br.readDouble();
            }
            int type = br.readChar();
            if (type == 0)
            {
                data.m_volume = br.readDouble();
                data.m_amount = br.readDouble();
            }
            else
            {
                data.m_volume = br.readInt();
                data.m_amount = br.readInt();
            }
            if (d < 2 && data.m_volume == 0)
            {
                continue;
            }
            datas->add(data);
        }
    }
}

ArrayList<Security*> HistoryServiceClient::getCodes(char* body, int bodyLength){
    FCBinary br;
    br.write(body, bodyLength);
    int datasSize = br.readInt();
    ArrayList<Security*> datas;
    for (int i = 0; i < datasSize; i++)
    {
        Security *security = new Security ;
        security->m_code = br.readString();
        security->m_name = br.readString();
        security->m_pingyin = br.readString();
        security->m_type = br.readChar();
        security->m_block = br.readString();
        datas.add(security);
    }
    return datas;
}

HashMap<String, ArrayList<ADJUSTMENTFACTOR*>> HistoryServiceClient::getFactors(char* body, int bodyLength){
    HashMap<String, ArrayList<ADJUSTMENTFACTOR*>> factors;
    FCBinary br;
    br.write(body, bodyLength);
    int size = br.readInt();
    for (int i = 0; i < size; i++)
    {
        String code = br.readString();
        int dfSize = br.readInt();
        ArrayList<ADJUSTMENTFACTOR*> aList;
        for (int j = 0; j < dfSize; j++)
        {
            ADJUSTMENTFACTOR *af = new ADJUSTMENTFACTOR;
            af->dwDate = (double)br.readInt() * 86400;
            af->f1 = br.readFloat();
            af->f2 = br.readFloat();
            af->f3 = br.readFloat();
            af->f4 = br.readFloat();
            aList.add(af);
        }
        factors.put(code, aList);
    }
    
    return factors;
}

#include "FCFile.h"

void HistoryServiceClient::onReceive(FCMessage *message){
    FCClientService::onReceive(message);
    if (message->m_functionID == FUNCTIONID_GETCODE)
    {
        ArrayList<Security*> securities = getCodes(message->m_body, message->m_bodyLength);
        DataCenter::getSecurityService()->load(securities);
    }
    else if (message->m_functionID == FUNCTIONID_GETDR)
    {
        m_factors = getFactors(message->m_body, message->m_bodyLength);
    }
    sendToListener(message);
}
